using System.Reflection;
using Core.Db.Dtos;
using Core.Db.Models;

namespace Core.Db.Services;

public class ProPertyMappingService : IProPertyMappingService
{
    private Dictionary<string, PropertyMappingValue> _touristRoutePropertyMapping = new Dictionary<string, PropertyMappingValue>(StringComparer.OrdinalIgnoreCase)
    {
        { "Id", new PropertyMappingValue(new[] { "Id" }) },
        { "Title", new PropertyMappingValue(new[] { "Title" }) },
        { "Rating", new PropertyMappingValue(new[] { "Rating" }) },
        { "OriginalPrice", new PropertyMappingValue(new[] { "OriginalPrice" }) },
    };

    private IList<IPropertyMapping> _propertyMappings = new List<IPropertyMapping>();

    public ProPertyMappingService()
    {
        _propertyMappings.Add(new PropertyMapping<TouristRouteDto, TouristRoute>(_touristRoutePropertyMapping));
    }

    public Dictionary<string, PropertyMappingValue> GetPropertyMapping<TSource, TDestination>()
    {
        //获取匹配的映射对象
        var matchingMapping = _propertyMappings.OfType<PropertyMapping<TSource, TDestination>>();
        if (matchingMapping.Count() >= 1)
        {
            return matchingMapping.First().MappingDictionary;
        }

        throw new Exception($"Cannot find exact property mapping instance for <{typeof(TSource)},{typeof(TDestination)}>");
    }

    public bool IsMappingExists<TSource, TDestination>(string fields)
    {
        var propertyMapping = GetPropertyMapping<TSource, TDestination>();
        if (string.IsNullOrWhiteSpace(fields))
        {
            return true;
        }

        var fieldsAfterSplit = fields.Split(',');
        foreach (var field in fieldsAfterSplit)
        {
            var trimmedField = field.Trim();
            var indexOfFirstSpace = trimmedField.IndexOf(" ");
            var propertyName = indexOfFirstSpace == -1 ? trimmedField : trimmedField.Remove(indexOfFirstSpace);

            if (!propertyMapping.ContainsKey(propertyName))
            {
                return false;
            }
        }

        return true;
    }

    public bool IsPropertiesExists<T>(string fields)
    {
        if (string.IsNullOrWhiteSpace(fields))
        {
            return true;
        }

        var fieldsAfterSplit = fields.Split(',');
        foreach (var field in fieldsAfterSplit)
        {
            var trimmedField = field.Trim();
            var propertyInfo = typeof(T).GetProperty(trimmedField, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
            if (propertyInfo == null)
            {
                return false;
            }
        }

        return true;
    }
}